let machine = require('../public/index.js');
const dao = require('./dao');
const hamburgerModel = new dao();
let dbDao = new dao();
const { order } = require('../db/schema');
class hamburger extends machine {
    constructor(httpClient, tcpServe) {
        // 窗口topic参数输入：this.topics = [{薯条机内窗口}]
        super(httpClient, tcpServe, [{ topic: 'hamburger_1206933677649645569' }]);
        this.toOrder = true;
        this.hamburgerInfo = {
            'nei': {
                date: '',
                _meadId: ''
            },
            'wai': {
                date: '',
                _meadId: ''
            }
        };     //当前下单
        this.listenKafka();
        this.hamburgerConnect();
        this.test();

    }
    test() {
        
    }
    receive(key, arr, type, randomNumber) {
        this.clients[key].deviceType = arr[0];
        this.clients[key].timestamp = (new Date()).getTime();  
        let res = {
            content: '',
            isSend: true
        };
        if (arr[0] === 170) {
            // 蛋糕机的头信息是AA，170对应的是蛋糕机设备
            switch (type) {
                case 1:
                    console.log("接收心跳");
                    this.updateStatus(arr, key);
                    this.getFreeOrder(key);
                    res.content = this.messageResponse(0);
                    break;
                case 3:
                    console.log("接收状态上报");
                    this.updateStatus(arr, key);
                    res.content = this.messageResponse(0);
                    break;
                case 4:
                    console.log("下单成功");
                    // TODO 修改改订单 菜品 数据库状态

                    res.isSend = false;
                    break;
                case 5:
                    console.log("PLC接收到出餐命令");
                    res.isSend = false;
                    break;
                case 6:
                    console.log("制餐完成指令");
                    // TODO 上报云端制餐完成,修改数据库订单
                    // 获取制作完成订单详情
                    let params = {_mealId:arr[4],date:this.date}
                    this.findOne(params,(res)=>{
                        let detail = JSON.parse(res.orderDetail);
                        this.postMealAbnormal({
                            storeId: this.storeId,
                            orderId: detail.orderId,
                            productId: detail.productId,
                            productStatus: '58',
                            orderDetailId: detail.id
                        } , (res) => {
                            hamburgerModel.updateOrder({date: this.date, _mealId: arr[4]}, {status: '2'});
                        });
                    });
                    res.content = this.messageResponse(0);
                    break;
                case 8:
                    console.log("取餐超时反馈");
                    // TODO 修改数据库该订单状态
                    // TODO 上报取餐超时信息
                    res.content = this.messageResponse(0);
                    break;
                case 9:
                    console.log("PLC已强制开门");
                    res.isSend = false;
                    break;


                default:
                    res.content = '';

            }
            return res;

        } else if (arr[0] === 10) {
            // 饮料机
            switch (type) {
                case 0:
                    console.log("接收心跳");
                    this.getFreeOrder(key);
                    this.updateStatus(arr, key);
                    break;
                case 1:
                    console.log("接收制作状态");
                    //TODO 告诉云端该菜品制作情况,修改数据库该订单情况
                    break;
                case 2:
                    console.log("客户端返回是否可以制餐");
                    if (arr[4] === 1) {
                        // TODO 修改设备状态为繁忙，修改数据库订单状态
                    }
                    res.isSend = false;
                    break;
                case 3:
                    console.log("接收状态上报");
                    this.updateStatus(arr, key);
                    // TODO 上报云端设备状态
                    break;
                case 4:
                    console.log("强制开门信息回复:");
                    if (arr[4] === 1) {
                        console.log("可以开门");
                    }
                    res.isSend = false;
                    break;
                default:
                    res.content = '';

            }
            return res;
        }
    }
    hamburgerConnect() {
        this.tcpConnect((socket) => {
            // 1代表hamburger,2代表
            let key = socket.remoteAddress;//每个用户的唯一标示
            // 设备首次连接触发
            let times = (new Date()).getTime();
            // 取餐口1（里面）、2（外面）
            let intakeStatus = { '1': 1, '2': 1 }
            //初始化设备状态
            // timestamp:设备最新心跳时间戳,workStatus:工作状态,controlStatus:控制模式,deviceStatus:设备状态,intakeStatus:设备层状态
            this.clients[key] = { socket, timestamp: times, workStatus: 2, controlStatus: 1, deviceStatus: 1, intakeStatus: intakeStatus, deviceType: '' };
            this.clientConnected(socket);
            this.tcpTimeout(socket, 10, () => {
                console.log("超时时间到，设备下线");
                socket.destroy();        //主动踢客户端下线
            });
        });
    }
    /**
   * 服务器连接时启动轮询调度
   * @param   
   */
    // scheduler() {
    //     // 每10秒查询在线设备情况
    //     setInterval(() => {
    //         console.log("开启定时")
    //         let times = (new Date()).getTime();
    //         for(let key in this.clients){
    //             this.tcpTimeout(this.clients[key].socket,60,()=>{
    //                 console.log("超时时间到，设备下线");
    //                 this.clients[key].socket.destroy();        //主动踢客户端下线
    //                 // 上报云端设备异常
    //                 let param = {};
    //                 this.postAbnormal(param);
    //             })
    //             console.log(this.clients[key]);
    //             if(this.clients[key].deviceStatus == 2) {
    //                 // 上报云端设备异常
    //                 let param = {};
    //                 this.postAbnormal(param);
    //                 continue;
    //             }
    //             if(this.clients[key].workStatus == 1 && (this.clients[key].intakeStatus['1'] == 1 || this.clients[key].intakeStatus['2'] == 1)){
    //                 // 可以执行正常下单调度
    //                 console.log("调度设备")
    //                 this.sendMakeMeal(() => {
    //                     this.sendMeal(key);   
    //                 })

    //             }

    //         }
    //     }, 5000);
    // }
    /**
     * 从数据库获取空闲订单并向PLC 下发制单指令
     * @param {socket key} key 
     */
    sendMeal(key) {
        let type = this.clients[key].deviceType;
        let window1 = this.clients[key].intakeStatus['1'];
        let window2 = this.clients[key].intakeStatus['2'];
        let content, topics, params;
        if (type == 170) {
            // 判断哪个窗口空闲
            if (window1 + window2 == 2) {
                // 两个窗口都空闲,寻找这两窗口中最新的一条订单制作
                params = {
                    status: 0,
                    $or: [{ topic: this.topics[0].topic }, { topic: this.topics[1].topic }],
                };
                order.findOne(params).sort('-_id').exec((err, res) => {
                    console.log('res', res);
                    this.date = res.date;
                    let meadId = res._mealId;
                    let intake = res.topic == this.topics[0].topic ? 1 : 2; //判断获取的窗口是否内外窗口
                    let detail = JSON.parse(res.orderDetail);
                    let productId = detail.productId;
                    let rows = this.toList(detail.rows, detail.columns, 4) //柜子默认是4列
                    let specinfoList = this.toSpecinfo(detail.specinfo);
                    content = this.messageResponse(170, 4, this.getRandom(), 16, meadId, productId, rows, specinfoList[0], specinfoList[1], specinfoList[2], specinfoList[3], intake);
                    this.tcpSend(key, content);
                })

            } else if (window1 + window2 == 3) {
                // 其中有一个窗口空闲
                topics = window1 == 1 ? this.topics[0].topic :  this.topics[1].topic;       //如果窗口1空闲则获取窗口1的订单topic
                params = {status:0,topic:topics};
                hamburgerModel.findOrder(params,(res) =>{
                    console.log('res', res);
                    this.date = res.date;
                    let intake = res.topic == this.topics[0].topic ? 1 : 2; //判断获取的窗口是否内外窗口
                    let detail = JSON.parse(res.orderDetail);
                    let meadId = res._mealId;
                    let productId = detail.productId;
                    let rows = this.toList(detail.rows, detail.columns, 4) //柜子默认是4列
                    let specinfoList = this.toSpecinfo(detail.specinfo);
                    content = this.messageResponse(170, 4, this.getRandom(), 16, meadId, productId, rows, specinfoList[0], specinfoList[1], specinfoList[2], specinfoList[3], intake);
                    this.tcpSend(key, content);
                });
            }

        } else if (type == 10) {
            if (window1 + window2 == 2) {
                // 两个窗口都空闲,寻找这两窗口中最新的一条订单制作
                params = {
                    status: 0,
                    $or: [{ topic: this.topics[2].topic }, { topic: this.topics[3].topic }],
                };
                order.findOne(params).sort('-_id').exec((err, res) => {
                    console.log('res', res);
                    this.date = res.date;
                    let intake = res.topic == this.topics[0].topic ? 1 : 2; //判断获取的窗口是否内外窗口
                    let detail = JSON.parse(res.orderDetail);
                    let meadId = res._mealId;
                    let productId = detail.productId;
                    let rows = this.toList(detail.rows, detail.columns, 4) //柜子默认是4列
                    let specinfoList = this.toSpecinfo(detail.specinfo);
                    content = this.messageResponse(10, 2, this.getRandom(), 28, meadId, productId, rows, specinfoList[0], specinfoList[1], specinfoList[2], specinfoList[3], intake);
                    this.tcpSend(key, content);
                })

            } else if (window1 + window2 == 3) {
                // 其中有一个窗口空闲
                topics = window1 == 1 ? this.topics[0].topic :  this.topics[1].topic;       //如果窗口1空闲则获取窗口1的订单topic
                params = {status:0,topic:topics};
                hamburgerModel.findOrder(params,(res) =>{
                    console.log('res', res);
                    this.date = res.date;
                    let intake = res.topic == this.topics[0].topic ? 1 : 2; //判断获取的窗口是否内外窗口
                    let detail = JSON.parse(res.orderDetail);
                    let meadId = res._mealId;
                    let productId = detail.productId;
                    let rows = this.toList(detail.rows, detail.columns, 4) //柜子默认是4列
                    let specinfoList = this.toSpecinfo(detail.specinfo);
                    content = this.messageResponse(10, 4, this.getRandom(), 28, meadId, productId, rows, specinfoList[0], specinfoList[1], specinfoList[2], specinfoList[3], intake);
                    this.tcpSend(key, content);
                });
            }
        }


    }
    /**
    * 更新PCL状态信息
    * @param {Object} data  接收的信息
    * @param {Object} key   PLC识别KEY
    */
    updateStatus(data, key) {
        console.log("设备上报");
        this.clients[key].controlStatus = data[4];
        this.clients[key].workStatus = data[5];
        this.clients[key].deviceStatus = data[6];
        this.clients[key].intakeStatus['1'] = data[7];
        this.clients[key].intakeStatus['1'] = data[8];
    }
    // 从数据库获取空闲订单
    getFreeOrder(key) {
        if (this.clients[key].workStatus == '1' && this.clients[key].deviceStatus == '1') {
            this.sendMeal(key);
        }
    }
    // 蛋糕机下发订单
    toOrderPLC(orderDetail) {
        this.sendMakeMeal(() => {
            this.getOrderDetail(body => {
            });
        })
    }
    // 蛋糕机制作完成
    hamburgerCompletion(arr) {
        let content;
        this.tcpSend(this.machineType, content);
    }
    // 获取扫描二维码取单
    hamburgerTakeMeal() {
        // 判断二维码订单是否和取餐订单相同，判断取餐口是否相同
        this.hamburgerOpenWindow();
    }
    // 通知PLC打开出餐口
    hamburgerOpenWindow() {
        let content;
        this.tcpSend(this.machineType, content);
    }
    // PCL发送订单超时
    hamburgerOverTime() {
    }

}
module.exports = hamburger;